package com.ruoyi.erecord.vehicles.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Service;

import com.ruoyi.common.tools.constant.ERecordConstant;
import com.ruoyi.common.tools.excel.MyExcelUtil;
import com.ruoyi.common.tools.excel.base.MyExcelResult;
import com.ruoyi.common.tools.excel.listener.VehiclesExcelListener;
import com.ruoyi.common.tools.utils.SerialGenerator;
import com.ruoyi.common.tools.zip.MyZipUtil;
import com.ruoyi.common.tools.zip.OssZipContent;
import com.ruoyi.common.tools.zip.ZipContent;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.erecord.vehicles.domain.bo.VehiclesImportAttachBo;
import com.ruoyi.erecord.vehicles.domain.bo.VehiclesImportBaseBo;
import com.ruoyi.erecord.vehicles.domain.bo.VehiclesImportBo;
import com.ruoyi.erecord.vehicles.domain.bo.VehiclesImportDetailBo;
import com.ruoyi.erecord.vehicles.domain.vo.VehiclesImportDetailVo;
import com.ruoyi.erecord.vehicles.service.IVehiclesImportAttachService;
import com.ruoyi.erecord.vehicles.service.IVehiclesImportBaseService;
import com.ruoyi.erecord.vehicles.service.IVehiclesImportDetailService;
import com.ruoyi.erecord.vehicles.service.IVehiclesService;
import com.ruoyi.system.service.ISysOssService;

import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RequiredArgsConstructor
@Service
public class VehiclesImportExcelService {
	private final ISysOssService sysOssService;
	private final IVehiclesImportAttachService vehiclesImportAttachService;
	private final IVehiclesImportBaseService vehiclesImportBaseService;
	private final IVehiclesImportDetailService vehiclesImportDetailService;
	private final IVehiclesService vehiclesService;

	/**
	 * 导入人员excel数据
	 * 
	 * @param bo
	 * @return
	 */
	public Boolean importExcel(VehiclesImportBaseBo bo) {
		// 生成批次号
		final String batchNo = SerialGenerator.generator.nextId();
		bo.setBatchNo(batchNo);

		// excel 处理
		MyExcelResult<VehiclesImportDetailVo> excelResult = MyExcelUtil.getImportExcelData(batchNo,
				bo.getExcelUrl(), new VehiclesExcelListener(batchNo), VehiclesImportDetailVo.class);

		if (null == excelResult) {
			return false;
		}

		// 更新主表状态
		if (excelResult.isSuccess()) {
			bo.setProcessStatus(ERecordConstant.COMMON_STATUS_SUCCESS);
		} else {
			bo.setProcessStatus(ERecordConstant.COMMON_STATUS_ERROR);
		}
		bo.setProcessMsg(excelResult.getAnalysis());
		bo.setAttachMsg(ERecordConstant.ATTACH_UPLOAD_STATUS_NO);
		// 入库主表
		if (this.vehiclesImportBaseService.insertByBo(bo)) {
			// 入库子表
			if (!excelResult.getList().isEmpty()) {
				if (!this.vehiclesImportDetailService.batchInsertBo(excelResult.getList())) {
					return false;
				}
			}
		} else {
			return false;
		}

		if (excelResult.isSuccess() && !excelResult.getList().isEmpty()) {
			// 更新车辆表
			this.vehiclesService.batchInsertOrUpdate(batchNo);
		}

		return true;
	}

	/**
	 * 导入 zip包
	 * 
	 * @param bo
	 * @return
	 */
	public Boolean importZip(VehiclesImportBo bo) {
		// 1.分包
		// 2.下载 zip包 解析 zip数据
		// 3.匹配 导入excel的明细数据，根据身份证

		if (StringUtils.isEmpty(bo.getDrivingLicensePic()) && StringUtils.isEmpty(bo.getTravelLicensePic())
				&& StringUtils.isEmpty(bo.getFrontPic()) && StringUtils.isEmpty(bo.getBehindPic())
				&& StringUtils.isEmpty(bo.getSidePic())) {
			return false;
		}

		final String batchNo = bo.getBatchNo();

		VehiclesImportDetailBo queryDetailBo = new VehiclesImportDetailBo();
		queryDetailBo.setBatchNo(batchNo);
		List<VehiclesImportDetailVo> detailVoList = this.vehiclesImportDetailService.queryList(queryDetailBo);

		if (null == detailVoList || detailVoList.isEmpty()) {
			return false;
		}

		List<VehiclesImportAttachBo> attachList = new ArrayList<>(20);

		// 驾驶证照片
		if (StringUtils.isNotEmpty(bo.getDrivingLicensePic())) {
			String[] pics = bo.getDrivingLicensePic().split(",");
			List<OssZipContent> ossZipList = MyZipUtil.getOssZipContents(pics, "驾驶证照片");
			attachList.addAll(this.processAttach(batchNo, detailVoList, ossZipList));
		}

		// 行驶证照片
		if (StringUtils.isNotEmpty(bo.getTravelLicensePic())) {
			String[] pics = bo.getTravelLicensePic().split(",");
			List<OssZipContent> ossZipList = MyZipUtil.getOssZipContents(pics, "行驶证照片");
			attachList.addAll(this.processAttach(batchNo, detailVoList, ossZipList));
		}
		
		// 正前面照片
		if (StringUtils.isNotEmpty(bo.getFrontPic())) {
			String[] pics = bo.getFrontPic().split(",");
			List<OssZipContent> ossZipList = MyZipUtil.getOssZipContents(pics, "正前面照片");
			attachList.addAll(this.processAttach(batchNo, detailVoList, ossZipList));
		}
		
		// 正侧面照片
		if (StringUtils.isNotEmpty(bo.getSidePic())) {
			String[] pics = bo.getSidePic().split(",");
			List<OssZipContent> ossZipList = MyZipUtil.getOssZipContents(pics, "正侧面照片");
			attachList.addAll(this.processAttach(batchNo, detailVoList, ossZipList));
		}
		
		// 正后面照片
		if (StringUtils.isNotEmpty(bo.getBehindPic())) {
			String[] pics = bo.getSidePic().split(",");
			List<OssZipContent> ossZipList = MyZipUtil.getOssZipContents(pics, "正后面照片");
			attachList.addAll(this.processAttach(batchNo, detailVoList, ossZipList));
		}
		
		int success = 0;
		int count = attachList.size();
		for (VehiclesImportAttachBo attach : attachList) {
			if (attach.getProcessStatus() == ERecordConstant.COMMON_STATUS_SUCCESS) {
				success++;
			}
		}

		if (this.vehiclesImportAttachService.batchInsertByBo(attachList)) {
			//
			this.vehiclesImportDetailService.batchUpdatetBo(detailVoList);
			
			if (count > 0 && count == success) {
				VehiclesImportBaseBo baseBo = new VehiclesImportBaseBo();
				baseBo.setBatchNo(batchNo);
				baseBo.setAttachMsg(ERecordConstant.ATTACH_UPLOAD_STATUS_YES);
				this.vehiclesImportBaseService.updateByBo(baseBo);

				// 主表导入
				this.vehiclesService.batchUpdate(detailVoList);
			}

			return true;
		} else {
			return false;
		}
	}

	private List<VehiclesImportAttachBo> processAttach(String batchNo, List<VehiclesImportDetailVo> detailList,
			List<OssZipContent> ossZipList) {
		List<VehiclesImportAttachBo> result = new ArrayList<>(ossZipList.size());
		final String tmp = "导入附件 {} 条数据，成功 {} 条，失败 {} 条";
		for (OssZipContent ossZip : ossZipList) {
			VehiclesImportAttachBo attachBo = new VehiclesImportAttachBo();
			attachBo.setBatchNo(batchNo);
			attachBo.setAttachUrl(ossZip.getOssId());
			attachBo.setFileName(ossZip.getFileName());
			attachBo.setAttachType(ossZip.getImportType());

			int count = ossZip.getZipContentList().size();
			int success = 0;
			int error = 0;

			// detailId : List<ZipContent> 同一个明细id有多个相同的附件上传
			Map<VehiclesImportDetailVo, List<ZipContent>> contentMap = new HashMap<>(ossZip.getZipContentList().size());
			for (ZipContent zipContent : ossZip.getZipContentList()) {
				boolean successFlag = false;
				for (VehiclesImportDetailVo detail : detailList) {
					String vehiclesNumber = detail.getVehiclesNumber() == null ? "" : detail.getVehiclesNumber();
					String[] tmpNames = zipContent.getName().split("[-]");
					if (vehiclesNumber.equals(tmpNames[0])) {
						success++;
						successFlag = true;
						// push 上传oss 对应的数据 ，再更新 detail 表的对应字段
						List<ZipContent> mapList = contentMap.get(detail);
						if (null == mapList) {
							mapList = new ArrayList<>();
							contentMap.put(detail, mapList);
						}
						mapList.add(zipContent);

						continue;
					}
				}
				if (successFlag == false) {
					error++;
				}
			}
			if (count == 0 || error > 0) {
				attachBo.setProcessStatus(ERecordConstant.COMMON_STATUS_ERROR);
			} else {
				attachBo.setProcessStatus(ERecordConstant.COMMON_STATUS_SUCCESS);
			}

			attachBo.setProcessMsg(StrUtil.format(tmp, count, success, error));

			this.processDetailAndOss(contentMap, ossZip.getImportType());

			result.add(attachBo);
		}

		return result;
	}

	private void processDetailAndOss(Map<VehiclesImportDetailVo, List<ZipContent>> contentMap, String importType) {
		for (Map.Entry<VehiclesImportDetailVo, List<ZipContent>> map : contentMap.entrySet()) {
			// 上传oss
			List<String> ossIdList = new ArrayList<>(map.getValue().size());
			for (ZipContent zip : map.getValue()) {
				String originalfileName = zip.getName() + zip.getSuffix();
				byte[] fileContent = zip.getFileIs();
				String ossId = this.sysOssService.upload(originalfileName, fileContent);
				ossIdList.add(ossId);
			}

			String ossIds = String.join(",", ossIdList);
			VehiclesImportDetailVo detailVo = map.getKey();

			switch (importType) {
			case "驾驶证照片":
				detailVo.setDrivingLicensePic(ossIds);
				break;
			case "行驶证照片":
				detailVo.setTravelLicensePic(ossIds);
				break;
			case "正前面照片":
				detailVo.setFrontPic(ossIds);
				break;
			case "正侧面照片":
				detailVo.setSidePic(ossIds);
				break;
			case "正后面照片":
				detailVo.setBehindPic(ossIds);
				break;
			default:
				break;
			}
		}
	}
}
